/**
 * Created by wangx08 on 2015-04-29.
 */

define(function (require, exports, module) {
    var $ = require("jquery");
    var dialog = require("dialogplus");
    var util = require("util");
    var ddl = require("dropdownlist");
    var tmpl = require("tmpl");
    require("permission");
    require("jqtree");
    require('authorize');
    var api_prefix = G_CONFIG["api_prefix"];
    var api_prefix_org = api_prefix + "usermanage/organization/"; //api前缀
    var api_prefix_user = api_prefix + "usermanage/user/"; //api前缀
    var angular = require("angular");
    require("angular-interceptor");
    require("pagination");
    require("angular-ui");
    require("./roleTree");

    var __seed = 0;

    function genClienUniqueID() {
        return "__" + parseInt(Math.random() * 10000) + "_" + (__seed++);
    }

    var app = angular
        .module("app", ["ngInterceptor", "ngUI", "roleTree"])

        /*
         .directive("treeNode", ['$compile', function ($compile) {
         return {
         restrict: 'A',
         replace: true,
         link: function ($scope, $element, $attrs) {

         }
         };
         })
         .directive("tree", ['$compile', function ($compile) {
         return {
         restrict: 'A',
         replace: true,
         link: function ($scope, $element, $attrs) {
         $scope.$watch("nodes",function(newValue,oldValue){
         $($element[0]).tree({
         data: newValue,
         dragAndDrop: false,
         useContextMenu:false,
         autoOpen:this.expandLevel, //展开级别
         //创建节点时
         onCreateLi: function(node, $li) {
         var content = $compile(html)(node);
         if (replace) {
         $element.replaceWith(content);
         } else {
         $element.html(content);
         }
         node.loadFromData(node.childNodes);
         },
         //是否可以移动
         onCanMove: function(node) {
         return false;
         },
         //是否可以移动到
         onCanMoveTo: function(moved_node, target_node,position){
         //只能在同级节点中移动
         return false;
         },
         //移动句柄
         onIsMoveHandle: function($ele) {
         return false;
         }
         });
         });
         }
         };
         })*/
        .service("commonService", [function () {
            var G_SUCCESSCODE = "0";
            return {
                getSuccessFn: getSuccessFn,
                errorFn: errorFn,
                extendGetFn: extendGetFn
            };
            function getSuccessFn(success) {
                return function (data) {
                    if (data.retCode == G_SUCCESSCODE) {
                        success && success(data);
                    }
                    else {
                        util.alert(data.errMsg || getErrMsg(data.retCode));
                    }
                };
            }

            function errorFn() {

            }

            function getErrMsg(code) {
                return code;
            }

            function extendGetFn(service) {
                var getServiceFn = {};
                for (var serName in service) {
                    getServiceFn[getServiceName(serName)] = (function (serv) {
                        return function () {
                            var args = argsToArr(arguments);
                            return function () {
                                serv.apply(null, args);
                            }
                        }
                    })(service[serName]);
                }
                return $.extend(getServiceFn, service);
            }

            function getServiceName(serName) {
                serName = serName[0].toUpperCase() + serName.substring(1);
                return "get" + serName + "Fn";
            }

            function argsToArr(args) {
                var arr = [];
                for (var i = 0; i < args.length; i++) {
                    arr.push(args[i]);
                }
                return arr;
            }
        }])
        .service("dataService", ["$http", "commonService", "$q", function ($http, commonService, $q) {
            var service = {
                "deleteOrganization": function (id, success) {
                    return noRequestInjectPost(api_prefix_org + "delete-organization&id=" + id, {}).success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },
                "queryAllOrganizations": function (success) {
                    return noRequestInjectGet(api_prefix_org + "query-all-organizations").success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },
                "queryAllCompany": function (success) {
                    return noRequestInjectGet(api_prefix_org + "query-all-company").success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },
                "queryAllERPCompanies": function (success) {
                    return noRequestInjectGet(api_prefix_org + "query-all-erp-companies").success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },
                "updateOrganizationOrderInLevel": function (data) {
                    return noRequestInjectPost(api_prefix_org + "update-organization-order-in-level", data);
                },
                "getCompanyInfo": function (id, success) {
                    return noRequestInjectGet(api_prefix_org + "get-company-info&id=" + id).success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },
                "getDepartInfo": function (id, success) {
                    return noRequestInjectGet(api_prefix_org + "get-depart-info&id=" + id).success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },
                "getTeamInfo": function (id, success) {
                    return noRequestInjectGet(api_prefix_org + "get-team-info&id=" + id).success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },
                "saveCompany": function (id, pid, data, success) {
                    return noRequestInjectPost(api_prefix_org + "save-company&id=" + (id || "") + "&pid=" + (pid || ""), data).success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },
                "saveDepart": function (id, pid, data, success) {
                    return noRequestInjectPost(api_prefix_org + "save-depart&id=" + (id || "") + "&pid=" + pid, data).success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },
                "saveTeam": function (id, pid, data, success) {
                    return noRequestInjectPost(api_prefix_org + "save-team&id=" + (id || "") + "&pid=" + pid, data).success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },

                "queryUserList": function (orgId, pageIndex, pageSize, sort, success) {
                    return noRequestInjectPost(api_prefix_user + "query-user-list&orgId=" + (orgId || "") + "&pageIndex=" + pageIndex + "&pageSize=" + pageSize, sort).success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },
                "updateUserRoles": function (uid, data, success) {
                    return noRequestInjectPost(api_prefix_user + "update-user-roles&id=" + uid, data).success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },
                "updateUserProjects": function (uid, data, success) {
                    return noRequestInjectPost(api_prefix_user + "update-user-projects&id=" + uid, data).success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },
                "updateUserTokens": function (uid, data, success) {
                    return noRequestInjectPost(api_prefix_user + "update-user-tokens&id=" + uid, data).success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },
                "queryProjectList": function (buguid, pageIndex, pageSize, data, success) {
                    return noRequestInjectGet(api_prefix + "common/project/list&buguid=" + buguid + "&pageIndex=" + pageIndex + "&pageSize=" + pageSize, {params: data}).success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },
                "changePassword": function (uid, password1, password2, success) {
                    return noRequestInjectPost(api_prefix_user + "change-password&id=" + uid + "&password1=" + password1 + "&password2=" + password2).success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },
                "updateDisableState": function (uid, disabled, reason, success) {
                    return noRequestInjectPost(api_prefix_user + "update-disable-state&id=" + uid + "&disabled=" + disabled, {reason: reason}).success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },
                "deleteUser": function (uid, success) {
                    return noRequestInjectPost(api_prefix_user + "delete-user&id=" + uid).success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },
                "saveUser": function (uid, data, success) {
                    return noRequestInjectPost(api_prefix_user + "save-user&id=" + (uid || ""), data).success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },
                "saveUserFullData": function (uid, data, success) {
                    return noRequestInjectPost(api_prefix_user + "save-user&id=" + (uid || "") + "&fullData=true", data).success(commonService.getSuccessFn(success)).error(commonService.errorFn);
                },

                "queryAllSettings": function (success) {
                    var result = {};

                    function getSetting(url, settingName) {
                        var pro = noRequestInjectGet(api_prefix + url);
                        pro.success(function (data) {
                            result[settingName] = data.data;
                        }).error(commonService.errorFn);
                        return pro;
                    }

                    $q.all([
                        getSetting("usermanage/role/query-all-roles", "allRoles"),
                        getSetting("config/bu-token/list", "allTokens"),
                        getSetting("usermanage/organization/query-all-company", "allCompanies")
                    ]).then(function () {
                        success && success(result);
                    }, function () {

                    });
                }
            };
            return commonService.extendGetFn(service);
            function noRequestInjectPost(url, data) {
                if (!data) {
                    data = {};
                }
                data = $.extend(data, {"NEED_TOKEN": false, "USE_FORM_DATA": false});
                return $http.post(url, data);
            }

            function noRequestInjectGet(url, data) {
                if (!data) {
                    data = {};
                }
                if (!data.params) {
                    data.params = {};
                }
                data.params = $.extend(data.params, {"NEED_TOKEN": false, "USE_FORM_DATA": false});
                return $http.get(url, data);
            }
        }])
        .factory("Notify", [function () {
            var fns = [];
            return {
                addOrgNodeChangedListener: function (callback) {
                    fns.push(callback);
                },
                orgNodeChanged: function (node, tree) {
                    angular.forEach(fns, function (fn) {
                        fn(node, tree);
                    });
                }
            };
        }])
        .directive("ngTokentree", ["$timeout", function ($timeout) {
            return {
                scope: {
                    "tokens": "=tokens",
                    "selects": "=selects",
                    "searchText": "=searchText"
                },
                link: function (scope, iEle, iAttr, ctrl) {
                    if (!scope.selects) {
                        scope.selects = [];
                    }
                    var $rTree = $(iEle[0]);
                    scope.$watch("searchText", function (newValue) {
                        if (!scope.tokens) {
                            return;
                        }
                        if (!newValue) {
                            $rTree.find("li").show();
                            return;
                        }
                        var node = null;
                        var ids = findTokenIdsByName(newValue, scope.tokens);
                        $rTree.find("li").hide();
                        angular.forEach(ids, function (id) {
                            node = $rTree.tree("getNodeById", id);
                            while (node) {
                                $(node.element).show();
                                node = node.parent;
                            }
                        });
                    });
                    scope.$watch("tokens", function (newValue, oldValue) {
                        if (!newValue) {
                            return;
                        }
                        $rTree.tree("destroy");
                        var treeData = fixedData(newValue);
                        $rTree
                            .tree({
                                data: treeData,
                                dragAndDrop: false,
                                useContextMenu: false,
                                selectable: true,
                                autoOpen: 0, //展开级别
                                //创建节点时
                                onCreateLi: function (node, $li) {
                                    if (node.token) {
                                        var id = "token_cb" + node.token + "_" + scope.id + genClienUniqueID();
                                        $li.find(".jqtree-title").prepend("<span class='checkbox'><input id='" + id + "' type='checkbox' value='" + node.token + "'><label for='" + id + "'>&nbsp;</label></span>");
                                    }
                                    $li.find(".jqtree-element").append("<div class='jqtree-extinfo'>" + (node.wxno || "") + "</div>");
                                },
                                //是否可以移动
                                onCanMove: function (node) {
                                    return false;
                                },
                                //是否可以移动到
                                onCanMoveTo: function (moved_node, target_node, position) {
                                    //只能在同级节点中移动
                                    return false;
                                },
                                //移动句柄
                                onIsMoveHandle: function ($ele) {
                                    return false;
                                },
                                onCanSelectNode: function (node) {
                                    return node.token;
                                }
                            })
                            .on('click', '.jqtree-element', function (e) {
                                var $item = $(this);

                                var $label = $item.find('label');

                                var target = e.target;

                                var $input = $item.find('input');
                                if ($input[0]) {
                                    if (!$.contains($label, target) && $label[0] !== target && $input[0] !== target) {
                                        $input.prop('checked', !$input.prop('checked'));
                                    }
                                }
                            });
                        updateSelectView();
                        $rTree.unbind("mouseup keyup").on("mouseup keyup", function () {
                            var s = scope;
                            $timeout(updateSelect);
                        });
                    });
                    function updateSelect() {
                        var selects = [];
                        $rTree.find("input[type='checkbox']:checked").each(function () {
                            selects.push($(this).val());
                        });
                        scope.selects = selects;
                    }

                    function updateSelectView() {
                        $rTree.find("input[type='checkbox']").prop("checked", false);
                        angular.forEach(scope.selects, function (item) {
                            $rTree.find("input[type='checkbox'][value='" + item + "']").prop("checked", true);
                        });
                    }

                    function findTokenIdsByName(name, tokens) {
                        var ids = [];
                        for (var i = 0; i < tokens.length; i++) {
                            if (tokens[i].name.indexOf(name) >= 0) {
                                ids.push(tokens[i].id);
                            }
                            if (tokens[i].nodes && tokens[i].nodes.length) {
                                var cids = findTokenIdsByName(name, tokens[i].nodes);
                                ids = ids.concat(cids);
                            }
                        }
                        return ids;
                    }
                }
            };
            function fixedData(tokens) {
                for (var i = 0; i < tokens.length; i++) {
                    var token = tokens[i];
                    if (token.nodes && token.nodes.length) {
                        fixedData(token.nodes);
                        token.children = token.nodes;
                    }
                    else if (!token.token) {
                        tokens.splice(i, 1);
                        i--;
                    }
                }
                return tokens;
            }
        }])
        .directive("ngCompanyTree", ["$timeout", "$parse", function ($timeout, $parse) {
            return {
                scope: {
                    "companies": "=companies"
                },
                link: function (scope, iEle, iAttr, ctrl) {
                    if (!scope.selects) {
                        scope.selects = [];
                    }
                    var $companyTree = $(iEle[0]);
                    var select = false;
                    var changeFn = iAttr.changed ? $parse(iAttr.changed, null, true) : angular.noop;
                    scope.$watch("companies", function (newValue, oldValue) {
                        if (!newValue) {
                            return;
                        }
                        $companyTree.tree("destroy");
                        if (newValue.length == 0)return;
                        var treeData = fixedData(newValue);
                        $companyTree.tree({
                            data: treeData,
                            dragAndDrop: false,
                            useContextMenu: false,
                            selectable: true,
                            autoOpen: 0, //展开级别
                            //创建节点时
                            onCreateLi: function (node, $li) {
                            },
                            //是否可以移动
                            onCanMove: function (node) {
                                return false;
                            },
                            //是否可以移动到
                            onCanMoveTo: function (moved_node, target_node, position) {
                                //只能在同级节点中移动
                                return false;
                            },
                            //移动句柄
                            onIsMoveHandle: function ($ele) {
                                return false;
                            },
                            onCanSelectNode: function (node) {
                                return true;
                            }
                        });
                        $companyTree.unbind("tree.click").on("tree.click", function (e) {
                            var node = e.node;
                            changeNode(node);
                        });
                        changeNode();
                        function changeNode(node) {
                            if (node) {
                                if (select != node.id) {
                                    select = node.id;
                                    changeFn(scope.$parent, {$select: select});
                                }
                            }
                            else {
                                if (select != newValue[0].id) {
                                    select = newValue[0].id;
                                    changeFn(scope.$parent, {$select: select});
                                }
                            }
                        }
                    });
                }
            };
            function fixedData(data) {
                angular.forEach(data, function (item) {
                    item.children = item.childNodes;
                    fixedData(item.childNodes);
                });
                return data;
            }
        }])
        .controller("ProjectSelect", ["$scope", "dataService", function ($scope, service) {
            var parentScope = $scope.$parent;//对应从UserList打开的dialog的scope
            $scope.companies = [];
            $scope.genClienUniqueID = genClienUniqueID;
            var userProjects = [];
            var userProjectsCache = {};
            parentScope.$watch("data", function (newValue) {
                if (newValue) {
                    $scope.companies = parentScope.data.companies;
                    userProjects = parentScope.data.row.projects;
                    userProjectsCache = {};
                    angular.forEach(userProjects, function (project) {
                        userProjectsCache[project.id] = project;
                    });
                    updateCheckState($scope.data.rows);
                }
            });

            $scope.search = {
                searchText: ""
            };
            $scope.data = {
                rows: [],
                queryProjectList: 1,
                pageSize: 10,
                pageCount: 1,
                total: 0,
                buguid: null
            };
            var updateCheckState = function (rows) {
                var isAll = true;
                angular.forEach(rows, function (item) {
                    item.checked = $scope.isUserProject(item.ProjectGUID);
                    isAll = item.checked && isAll;
                });
                $scope.checkedAll = isAll;
            };
            var updateUserProject = function (row) {
                var checked = row.checked;
                if (checked) {
                    if (!userProjectsCache[row.ProjectGUID]) {
                        var proj = {id: row.ProjectGUID, name: row.ProjName};
                        userProjectsCache[row.ProjectGUID] = proj;
                        userProjects.push(proj);
                    }
                }
                else {
                    if (userProjectsCache[row.ProjectGUID]) {
                        for (var i = 0; i < userProjects.length; i++) {
                            if (userProjects[i].id == row.ProjectGUID) {
                                userProjects.splice(i, 1);
                                break;
                            }
                        }
                        delete userProjectsCache[row.ProjectGUID];
                    }
                }
            };
            $scope.$watch("data.rows", function (newValue) {
                updateCheckState(newValue);
            });
            $scope.change = function (buguid) {
                $scope.data.buguid = buguid;
                $scope.refrash();
            };
            $scope.isUserProject = function (projId) {
                return !!userProjectsCache[projId];
            };
            $scope.selectProject = function (row) {
                updateUserProject(row);
                updateCheckState($scope.data.rows);
            };
            $scope.checkedAll = false;
            $scope.selectAll = function () {
                var rows = $scope.data.rows;
                angular.forEach(rows, function (row) {
                    row.checked = $scope.checkedAll;
                    updateUserProject(row);
                });
            };
            $scope.$on("distory", function () {
                console.log(arguments);
            });
            $scope.refrash = function (pageIndex) {
                if (typeof pageIndex == "undefined")pageIndex = 1;

                $scope.data.pageIndex = pageIndex;
                service.queryProjectList($scope.data.buguid, $scope.data.pageIndex - 1, $scope.data.pageSize, {searchText: $scope.search.searchText}, function (data) {
                    $scope.data.rows = data.data.items;
                    $scope.data.pageIndex = data.data.pageIndex + 1;
                    $scope.data.pageCount = Math.max(1, Math.ceil(data.data.total / $scope.data.pageSize));
                    $scope.data.total = data.data.total;

                    parentScope.resetDialog();
                });
            };

        }])
        .controller("OrgTreeCtrl", ["$scope", "$location", "$http", "dataService", "Notify", function ($scope, $location, $http, service, notify) {
            var $tree = $("#tree_table");
            var btns = "编辑 删除 下移";
            var orgTree = [];
            var genTreeBtn = function (id) {
                return "<div style='width:160px;' class='jqtree-btn' data-unit-id='" + id + "'>\
                        <a class=' permission p-0000210202-02-inline-block' style='margin-left:5px;' data-trigger='edit'><i class='icon-op-edit'>&nbsp;</i></a>\
                        <a class=' permission p-0000210202-03-inline-block' style='margin-left:5px;' data-trigger='dele' ><i class='icon-op-del'>&nbsp;</i></a>\
                        <a class=' permission p-0000210202-02-inline-block' style='margin-left:5px;' data-trigger='moveup'><i class='icon-op-up'>&nbsp;</i></a>\
                        <a class=' permission p-0000210202-02-inline-block' style='margin-left:5px;' data-trigger='movedown'><i class='icon-op-down'>&nbsp;</i></a>\
                    </div>";
            };
            var genTreeBtnWithoutSort = function (id) {
                return "<div style='width:160px;' class='jqtree-btn' data-unit-id='" + id + "'>\
                        <a class=' permission p-0000210202-02-inline-block' style='margin-left:5px;' data-trigger='edit'><i class='icon-op-edit'>&nbsp;</i></a>\
                        <a class=' permission p-0000210202-03-inline-block' style='margin-left:5px;' data-trigger='dele' ><i class='icon-op-del'>&nbsp;</i></a>\
                    </div>";
            };
            var config = [
                {
                    name: "公司",
                    url: "company",
                    saveFn: "saveCompany",
                    getFn: service.getCompanyInfo
                }, {
                    name: "部门",
                    url: "depart",
                    saveFn: "saveDepart",
                    getFn: service.getDepartInfo
                }, {
                    name: "团队",
                    url: "team",
                    saveFn: "saveTeam",
                    getFn: service.getTeamInfo
                }
            ];
            var commands = {
                edit: function (tree, id) {
                    var node = tree.getNodeById(id);
                    var type = node.type;
                    var parentNode = node.parent;
                    var cfg = config[type] || config[2];
                    cfg.getFn(id, function (data) {
                        commands.editData(cfg, data.data, {
                            parentId: parentNode ? parentNode.id : null,
                            parentName: parentNode ? parentNode.name : ""
                        });
                    });
                },
                editData: function (cfg, data, parent) {
                    $scope.editModel.dialog = "编辑" + cfg.name;
                    $scope.editModel.data = $.extend(data, parent, {erpList: $scope.erpList});
                    $scope.editModel.saveData = $scope[cfg.saveFn];
                    $scope.editModel.url = cfg.url;
                    setTimeout(function () {
                        $("#editCmd").click();
                    });
                },
                dele: function (tree, id) {
                    util.confirm("确定要删除吗？", {
                        ok: service.getDeleteOrganizationFn(id, function () {
                            util.alert("删除成功！");
                            var node = tree.getNodeById(id);
                            $tree.tree('removeNode', node);

                            $tree.find(".jqtree-element:eq(0)").click();
                        })
                    });
                },
                moveup: function (tree, id) {
                    var node = tree.getNodeById(id);
                    var preNode = node.getPreviousNode();
                    if (preNode) {
                        commands.swap(tree, preNode, node);
                    }
                },
                movedown: function (tree, id) {
                    var node = tree.getNodeById(id);
                    var nextNode = node.getNextNode();
                    if (nextNode) {
                        commands.swap(tree, node, nextNode);
                    }
                },
                swap: function (tree, node1, node2) {
                    $tree.tree('moveNode', node1, node2, "after");
                    var data = [
                        {id: node1.id, order: node1.parent.getChildIndex(node1) + 1},
                        {id: node2.id, order: node2.parent.getChildIndex(node2) + 1}
                    ];
                    service.updateOrganizationOrderInLevel(data);
                }
            };
            service.queryAllOrganizations(function (data) {
                var treeData = fixedData(data.data);
                orgTree = treeData;
                $tree.tree({
                    data: treeData,
                    dragAndDrop: false,
                    useContextMenu: false,
                    autoOpen: 0, //展开级别
                    //创建节点时
                    onCreateLi: function (node, $li) {
                        if (node.parentId) {
                            $li.find(".jqtree-element").append(genTreeBtn(node.id));
                        }
                        else {
                            $li.find(".jqtree-element").append(genTreeBtnWithoutSort(node.id));
                        }
                    },
                    //是否可以移动
                    onCanMove: function (node) {
                        return false;
                    },
                    //是否可以移动到
                    onCanMoveTo: function (moved_node, target_node, position) {
                        //只能在同级节点中移动
                        return false;
                    },
                    //移动句柄
                    onIsMoveHandle: function ($ele) {
                        return false;
                    }
                });
                var root = $tree.tree("getTree").children[0];
                for (var type in $scope.def) {
                    $scope.def[type].parentId = root.id;
                    $scope.def[type].parentName = root.name;
                }

                $tree.tree('selectNode', root);

                notify.orgNodeChanged(root, orgTree);

                $tree.bind("tree.click", function (e) {
                    var node = e.node;
                    if (node) {
                        if (e.click_event) {
                            $item = $(e.click_event.target);
                            if ($item.is(".jqtree-btn a i")) {
                                $item = $item.parent();
                                var cmd = $item.attr("data-trigger");
                                var id = $item.parent().attr("data-unit-id");
                                var tree = $tree.tree("getTree");
                                commands[cmd](tree, id);
                            }
                        }
                        for (var type in $scope.def) {
                            $scope.def[type].parentId = node.id;
                            $scope.def[type].parentName = node.name;
                        }
                        notify.orgNodeChanged(node, orgTree);
                    }
                    else {
                        var root = $tree.tree("getTree").children[0];
                        for (var type in $scope.def) {
                            $scope.def[type].parentId = root.id;
                            $scope.def[type].parentName = root.name;
                        }
                        notify.orgNodeChanged(root, orgTree);
                    }
                });
            });
            $scope.def = {
                company: {
                    "parentId": null,
                    "name": "",
                    "fullName": "",
                    "code": "",
                    "erpId": "",
                    "erpName": "",
                    "companyAddr": "",
                    "webSite": "",
                    "fax": "",
                    "charter": "",
                    "corporationDeputy": "",
                    "comments": "",
                    erpList: []
                },
                depart: {},
                team: {}
            };
            $scope.erpList = [];
            service.queryAllERPCompanies(function (data) {
                $scope.erpList = data.data;
                $scope.editModel.data.erpList = $scope.erpList;
                $scope.def.company.erpList = $scope.erpList;
                $scope.def.company.erpId = $scope.erpList[0].id;
            });
            $scope.checkCanAdd = function (type, data, dialog) {
                data = data || $scope.def[['company', 'depart', 'team'][type]];
                var tree = $tree.tree("getTree");
                var node = tree.getNodeById(data.parentId);
                if (node.type > type) {
                    dialog.close();
                    var names = ["公司", "部门", "团队"];
                    util.alert("部门下不能新增公司，团队下不能新增公司和部门。");
                }
            };
            $scope.saveCompany = function (company) {
                if (company.erpId)company.erpName = getErpName(company.erpId);
                return service.saveCompany(company.id, company.parentId, company, function (data) {
                    updateTree(data.data.id, company.parentId, data.data);
                });
            };
            $scope.saveDepart = function (depart) {
                return service.saveDepart(depart.id, depart.parentId, depart, function (data) {
                    updateTree(data.data.id, depart.parentId, data.data);
                });
            };
            $scope.saveTeam = function (team) {
                return service.saveTeam(team.id, team.parentId, team, function (data) {
                    updateTree(data.data.id, team.parentId, data.data);
                });
            };
            $scope.editModel = {
                dialog: "编辑公司",
                data: {},
                saveData: function () {
                },
                url: ""
            };
            function updateTree(nodeId, parentId, nodeInfo) {
                var node = $tree.tree("getNodeById", nodeId);
                if (node) {
                    $tree.tree("updateNode", node, nodeInfo);
                }
                else {
                    var parent = $tree.tree("getNodeById", parentId);
                    $tree.tree("appendNode", nodeInfo, parent);
                }
            }

            function getErpName(id) {
                var name = null;
                angular.forEach($scope.erpList, function (item) {
                    if (item.id == id) {
                        name = item.name;
                        return false;
                    }
                });
                return name;
            }

            function fixedData(data) {
                angular.forEach(data, function (item) {
                    item.children = item.childNodes;
                    fixedData(item.childNodes);
                });
                return data;
            }
        }])
        .controller("UserList", ["$scope", "$location", "$http", "dataService", "Notify", function ($scope, $location, $http, service, notify) {
            notify.addOrgNodeChangedListener(orgNodeChanged);
            var configData = $scope.configData = {
                allTokens: [],
                allRoles: {},
                allCompanies: []
            };
            $scope.orgId = null;
            $scope.refrash = function (pageIndex) {
                if (!(orgTreeInited && setttingInited)) {
                    return;
                }

                if (typeof pageIndex == "undefined")pageIndex = 1;

                $scope.data.pageIndex = pageIndex;
                service.queryUserList($scope.orgId, $scope.data.pageIndex - 1, $scope.data.pageSize, {searchText: $scope.search.searchText}, function (data) {
                    $scope.data.rows = data.data.items;
                    angular.forEach($scope.data.rows, function (row) {
                        row.buname = getBuNameById(row.buguid);
                    });
                    $scope.data.pageIndex = data.data.pageIndex + 1;
                    $scope.data.pageCount = Math.max(1, Math.ceil(data.data.total / $scope.data.pageSize));
                    $scope.data.total = data.data.total;
                });
            };
            $scope.data = {
                rows: [],
                pageIndex: 1,
                pageCount: 1,
                total: 0
            };
            $scope.search = {
                searchText: ""
            };
            $scope.getRoleNames = function (roleIds) {
                var roleNames = [];
                findRoles(configData.allRoles.companyRoles);
                findRoles(configData.allRoles.groupRoles);
                return roleNames.join(",");
                function findRoles(roles) {
                    angular.forEach(roles, function (role) {
                        if (util.inArray(role.id, roleIds)) {
                            roleNames.push(role.name);
                        }
                    });
                }
            };
            $scope.getProjectNames = function (projects) {
                var names = [];
                angular.forEach(projects, function (project) {
                    names.push(project.name);
                });
                return names.join(",");
            };
            $scope.getTokenNames = function (tokenIds) {
                var tokenNames = [];
                findTokens(configData.allTokens);
                return tokenNames.join(",");
                function findTokens(tokens) {
                    angular.forEach(tokens, function (token) {
                        if (util.inArray(token.token, tokenIds)) {
                            tokenNames.push(token.name);
                        }
                        findTokens(token.nodes);
                    });
                }
            };
            var successAlert = function () {
                util.alert("保存成功！");
            };
            $scope.saveUserRoles = function (user) {
                var row = getRowById(user.id);
                row && (row.roles = user.roles);
                service.updateUserRoles(user.id, user.roles, successAlert);
            };
            $scope.saveUserProjects = function (user) {
                var row = getRowById(user.id);
                row && (row.projects = user.projects);
                service.updateUserProjects(user.id, toProjGUIDArr(user.projects), successAlert);
                function toProjGUIDArr(projects) {
                    var idArr = [];
                    angular.forEach(projects, function (project) {
                        idArr.push(project.id);
                    });
                    return idArr;
                }
            };
            $scope.saveUserTokens = function (user) {
                var row = getRowById(user.id);
                row && (row.tokens = user.tokens);
                service.updateUserTokens(user.id, user.tokens, successAlert);
            };
            $scope.saveUserPassword = function (data) {
                var id = data.row.id;
                var password1 = data.password1;
                var password2 = data.password2;
                service.changePassword(id, password1, password2, successAlert);
            };
            $scope.updateDisableState = function (user, disable) {
                var row = getRowById(user.id);
                var id = user.id;
                if (disable) {
                    util.confirm("确定要禁用吗？", {
                        ok: service.getUpdateDisableStateFn(id, disable, "", function () {
                            row.isDisabled = disable;
                            util.alert("操作成功！");
                        })
                    });
                }
                else {
                    service.updateDisableState(id, disable, "", function () {
                        row.isDisabled = disable;
                        util.alert("操作成功！");
                    });
                }
            };
            $scope.saveUser = function (user) {
                var row = getRowById(user.id);
                service.saveUser(user.id, user, function (data) {
                    for (var pname in $scope.def.user) {
                        if (typeof($scope.def.user[pname]) == "object")continue;
                        row[pname] = data.data[pname];
                    }
                    util.alert("保存成功！");
                });
            };
            $scope.deleteUser = function (user) {
                var id = user.id;
                util.confirm("确定要删除吗？", {
                    ok: service.getDeleteUserFn(id, function () {
                        util.alert("删除成功！");
                        $scope.refrash();
                    })
                });
            }
            $scope.def = {
                user: {
                    buguid: "",
                    buname: "",
                    comments: "",
                    email: "",
                    homePhone: "",
                    isAdmin: 0,
                    isDisabled: false,
                    jobNum: "",
                    mobilePhone: "",
                    officePhone: "",
                    password: null,
                    userCode: "",
                    userName: "",
                    roles: [],
                    tokens: [],
                    projects: []
                }
            };
            $scope.saveNewUser = function (user) {
                return service.saveUserFullData(null, user, function (data) {
                    successAlert();
                    $scope.refrash();
                });
            };
            var setttingInited = false;
            var orgTreeInited = false;
            var nodeOrgTree = [];
            service.queryAllSettings(function (data) {
                configData = $scope.configData = data;
                setttingInited = true;
                $scope.refrash();
            });
            function orgNodeChanged(node, tree) {
                $scope.orgId = node.id;
                $scope.def.user.buguid = node.id;
                $scope.def.user.buname = node.name;
                nodeOrgTree = tree;
                orgTreeInited = true;
                $scope.refrash();
            }

            function getRowById(uid) {
                for (var i = 0; i < $scope.data.rows.length; i++) {
                    if ($scope.data.rows[i].id == uid) {
                        return $scope.data.rows[i];
                    }
                }
                return null;
            }

            function getBuNameById(buguid) {
                return getBuNameFromNodesById(buguid, nodeOrgTree);
            }

            function getBuNameFromNodesById(buguid, nodes) {
                for (var i = 0; i < nodes.length; i++) {
                    if (angular.uppercase(nodes[i].id) == angular.uppercase(buguid)) {
                        return nodes[i].name;
                    }
                    var name = getBuNameFromNodesById(buguid, nodes[i].children);
                    if (name) {
                        return name;
                    }
                }
                return "";
            }
        }]);
    // 对话框控件
    var userStepDialogDirective = function ($compile, $document, $rootScope, $parse, $q, $http, $timeout) {
        var templateCache = {};
        var loadTemplate = function (url) {
            var deferred = $q.defer();
            var template = templateCache[url];
            if (template) {
                deferred.resolve(template);
            } else {
                $http.get(url).success(function (data) {
                    templateCache[url] = data;
                    deferred.resolve(data);
                }).error(function (reason) {
                    deferred.reject(reason);
                });
            }

            return deferred.promise;
        };

        return {
            restrict: 'A',
            compile: function (tElement, tAttrs, transcludeFn) {
                return function (scope, element, attrs, controller, transcludeFn) {
                    element.on('click', function () {
                        var title = attrs.uiUserStepDialog || tAttrs.uiUserStepDialog || "";
                        var fnNextSteps = scope.$eval(attrs.uiDialogNext || tAttrs.uiDialogNext) || [];
                        loadTemplate(attrs.uiDialogUrl).then(function (template) {
                            var dialogScope;
                            var dialogElement;
                            if (!dialogScope) {
                                dialogElement = angular.element('<div style="display: none;">' + template + '</div>');
                                dialogElement.appendTo($document[0].body);
                                var dialogLink = $compile(dialogElement);
                                dialogScope = $rootScope.$new(true);
                                dialogLink(dialogScope);
                            }
                            dialogScope.$stepIndex = 0;
                            dialogScope.$stepCount = fnNextSteps.length;

                            require.async("dialog", function (dialog) {
                                $timeout(function () {
                                    dialogScope.parent = scope;
                                    if (attrs.uiDialogData) {
                                        dialogScope.data = angular.copy(scope.$eval(attrs.uiDialogData));
                                    } else {
                                        dialogScope.data = {};
                                    }

                                    var showCallback = $parse(attrs.uiDialogShow, null, true);
                                    scope.$apply(function () {
                                        showCallback(scope, {
                                            $data: dialogScope.data,
                                            $dialog: dialogModel,
                                            $dialogScope: dialogScope
                                        });
                                    });

                                    // 重置 $submitted
                                    for (var p in dialogScope) {
                                        if (dialogScope.hasOwnProperty(p)) {
                                            var form = dialogScope[p];
                                            if (form && form.$submitted !== undefined) {
                                                form.$submitted = false;
                                            }
                                        }
                                    }
                                    dialogModel.reset();
                                });
                                var nextStepFn = function () {
                                    var result = true;
                                    for (var p in dialogScope) {
                                        if (dialogScope.hasOwnProperty(p)) {
                                            var form = dialogScope[p];
                                            if (form && form.$submitted !== undefined) {
                                                dialogScope.$apply(function () {
                                                    form.$submitted = true;
                                                });
                                                if (form.$invalid === true) {
                                                    // 如果表单经过修改并且验证失败，返回 false
                                                    return false;
                                                }
                                            }
                                        }
                                    }

                                    // 按钮正在处理
                                    if (inProgress) {
                                        return false;
                                    }
                                    inProgress = true;
                                    scope.$apply(function () {
                                        var index = dialogScope.$stepIndex;
                                        var fn = fnNextSteps[index];
                                        if (fn) {
                                            fn = $parse(fn, null, true);
                                            result = fn(scope, {
                                                $data: dialogScope.data,
                                                $dialog: dialogModel,
                                                $dialogScope: dialogScope
                                            });
                                        }
                                        else {
                                            result = true;
                                        }
                                    });
                                    var next = function (ifClose) {
                                        if (dialogScope.$stepIndex + 1 == dialogScope.$stepCount) {
                                            if (ifClose)dialogModel.close();
                                            return true;
                                        }
                                        else {
                                            dialogScope.$stepIndex++;
                                            dialogScope.$applyAsync(function () {
                                                setTimeout(function () {
                                                    dialogModel.reset();
                                                });
                                            });
                                            dialogModel._$('button').unbind();
                                            dialogModel.button(getButtonsByStep(dialogScope.$stepIndex, dialogScope.$stepCount));
                                            return false;
                                        }
                                    };
                                    if (result && typeof result.then === 'function' && typeof result['catch'] === 'function' && typeof result['finally'] === 'function') {
                                        // 如果是 Promise 对象则延迟关闭
                                        var promise = result;
                                        promise.then(function () {
                                            next(true);
                                        })['finally'](function () {
                                            // 异步处理完毕，允许按钮再次被点击
                                            inProgress = false;
                                        });
                                        return false;
                                    } else {
                                        // 同步处理完毕，允许按钮再次被点击
                                        inProgress = false;
                                    }
                                    if (result) {
                                        return next();
                                    }
                                    return result;
                                };
                                var cancelFn = function () {
                                    return true;
                                };
                                var preFn = function () {
                                    dialogScope.$stepIndex--;
                                    dialogModel._$('button').unbind();
                                    dialogModel.button(getButtonsByStep(dialogScope.$stepIndex, dialogScope.$stepCount));
                                    dialogScope.$applyAsync(function () {
                                        setTimeout(function () {
                                            dialogModel.reset();
                                        });
                                    });
                                    return false;
                                };
                                var wrapFn = function (fn) {
                                    return function () {
                                        var res = fn();
                                        return res;
                                    };
                                }
                                var getButtonsByStep = function (index, count) {
                                    var buttons = [];
                                    if (index > 0) {
                                        buttons.push({id: "pre" + index, value: "上一步", callback: wrapFn(preFn)});
                                    }
                                    if (index < count - 1) {
                                        buttons.push({id: "next" + index, value: "下一步", callback: wrapFn(nextStepFn)});
                                    }
                                    if (index == count - 1) {
                                        buttons.push({id: "next" + index, value: "确定", callback: wrapFn(nextStepFn)});
                                    }
                                    buttons.push({id: "cancel" + index, value: "取消", callback: wrapFn(cancelFn)});
                                    return buttons;
                                };

                                var inProgress = false; // 标示确认按钮正在处理，防止多次点击
                                var dialogModel = dialog({
                                    title: title,
                                    fixed: true,
                                    content: dialogElement[0]
                                }).showModal();
                                dialogModel._$('button').unbind();
                                dialogModel.button(getButtonsByStep(dialogScope.$stepIndex, dialogScope.$stepCount));

                                dialogScope.resetDialog = function () {
                                    setTimeout(function () {
                                        dialogModel && dialogModel.reset();
                                    }, 0);
                                };
                                //dialogScope.$stepIndex = 0;
                                //dialogScope.$stepCount = fnNextSteps.count;
                            });
                        });
                    });
                };
            }
        };
    };
    app.directive('uiUserStepDialog', ['$compile', '$document', '$rootScope', '$parse', '$q', '$http', '$timeout', userStepDialogDirective]);
    angular.bootstrap(document, ['app']);
});